package com.wyd.wenyongdaAdmin.xo.admin.menu.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wyd.wenyongdaAdmin.commons.model.admin.menu.dto.MenuDTO;
import com.wyd.wenyongdaAdmin.commons.model.admin.menu.dto.TreeMenuDTO;

import com.wyd.wenyongdaAdmin.commons.model.admin.menu.entity.MenuEntity;
import com.wyd.wenyongdaAdmin.commons.model.admin.menu.vo.VueRouterMetaVO;
import com.wyd.wenyongdaAdmin.commons.model.admin.menu.vo.VueRouterVO;
import com.wyd.wenyongdaAdmin.xo.admin.menu.mapper.MenuMapper;
import com.wyd.wenyongdaAdmin.xo.admin.menu.service.IMenuService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;



@Import(cn.hutool.extra.spring.SpringUtil.class)
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, MenuEntity> implements IMenuService {

    private static final Logger logger = LoggerFactory.getLogger(MenuServiceImpl.class);

    private  MenuMapper menuMapper;

    @Autowired
    public void setMenuMapper(MenuMapper menuMapper) {
        this.menuMapper = menuMapper;
    }


    @Override
    public List<TreeMenuDTO> selectAllMenu() {
        QueryWrapper<MenuEntity> queryWrapper = new QueryWrapper<MenuEntity>().orderBy(true,true,"sort");
        List<MenuEntity> menuEntityList = menuMapper.selectList(queryWrapper);
        List<TreeMenuDTO> menu = new ArrayList<>();
        TreeMenuDTO treeMenuDTO = null;
        for (MenuEntity menuEntity : menuEntityList) {
            treeMenuDTO = new TreeMenuDTO();
            BeanUtil.copyProperties(menuEntity, treeMenuDTO);
            menu.add(treeMenuDTO);
        }
        return menu;
    }

    @Override
    public List<TreeMenuDTO> getCurrentMenu(Long roleId) {
        List<TreeMenuDTO> childrenMenu = this.menuMapper.getChildrenMenuByRoleId(roleId);
        Set<Long> parentIds = new HashSet<>();
        if (childrenMenu.size() > 0) {
            for (TreeMenuDTO treeMenuDTO : childrenMenu) {
                parentIds.add(treeMenuDTO.getParentId());
            }
            List<TreeMenuDTO> parentMenu = this.getParentMenu(parentIds);
            List<TreeMenuDTO> currentMenu = new ArrayList<>(parentMenu);
            currentMenu.addAll(childrenMenu);
            return currentMenu;
        } else {
            return null;
        }

    }

    @Override // 4 9
    public List<TreeMenuDTO> getParentMenu(Set<Long> parentIds) {
        // 4 9
        List<TreeMenuDTO> parentMenuByParentId = this.menuMapper.getParentMenuByParentIds(parentIds);
        // 目前只查询出二级菜单的父菜单id
        // 如果是三级菜单还需继续查询 需要递归
        for (TreeMenuDTO treeMenuDTO : parentMenuByParentId) {
            if (treeMenuDTO.getParentId() != null && treeMenuDTO.getParentId() != -1) {
                if (parentIds.contains(treeMenuDTO.getParentId())) {
                    return parentMenuByParentId;
                }
                // 清空set
                parentIds.clear();
                // 1
                parentIds.add(treeMenuDTO.getParentId());
                // 递归
                parentMenuByParentId.addAll(getParentMenu(parentIds));
                return parentMenuByParentId;
            }
        }
        return parentMenuByParentId;
    }

    @Override
    public List<TreeMenuDTO> buildTree(List<TreeMenuDTO> menu) {
        List<TreeMenuDTO> trees = new ArrayList<>();
        Set<Long> ids = new HashSet<>();
        for (TreeMenuDTO treeMenu : menu) {
            // 如果是一级菜单
            if (treeMenu.getParentId() == null || treeMenu.getParentId() == -1) {
                // 添加
                trees.add(treeMenu);
            }

            for (TreeMenuDTO it : menu) {
                // 如果 父菜单id 等于 子菜单 parentId
                if (treeMenu.getId().equals(it.getParentId())) {
                    // 父菜单 childern 为空
                    if (treeMenu.getChildren() == null) {

                        treeMenu.setChildren(new ArrayList<>());
                    }
                    treeMenu.getChildren().add(it);
                    ids.add(it.getId());
                }
            }
        }
        if (trees.size() == 0) {
            trees = menu.stream().filter(s -> !ids.contains(s.getId())).collect(Collectors.toList());
        }

        return trees;
    }

    @Override
    public List<VueRouterVO> buildVueRouters(List<TreeMenuDTO> treeMenu) {
        List<VueRouterVO> list = new LinkedList<>();
        for (TreeMenuDTO menu : treeMenu) {
            if(menu != null) {
                // 获取子菜单
                List<TreeMenuDTO> menuDtoList = menu.getChildren();
                // 实例化vue路由对象
                VueRouterVO vueRouter = new VueRouterVO();
                // 判断是不是需要路由的菜单
                if (menu.getPath() != null && menu.getComponent() != null) {
                    vueRouter.setName(menu.getEnname())
                            .setPath(menu.getPath())
                            //.setComponent("_import"+"("+menu.getComponent()+")")
                            .setComponent(menu.getComponent())
                            .setMeta(new VueRouterMetaVO(menu.getTitle(), true));
                    list.add(vueRouter);
                }
                // 子菜单不为空
                if (menuDtoList != null && menuDtoList.size() != 0) {
                    // 迭代子菜单 并 合并 list
                    list.addAll(buildVueRouters(menuDtoList));
                }
            }
        }
        return list;
    }

    @Override
    public Integer addMenu(MenuDTO menuDTO) {
        if (ObjectUtil.isNotNull(menuDTO)) {
            MenuEntity menu = new MenuEntity();
            BeanUtil.copyProperties(menuDTO, menu);
            return this.menuMapper.insert(menu);
        } else {
            return 0;
        }
    }

    @Override
    public Integer updateMenu(MenuDTO menuDTO) {
        if (ObjectUtil.isNotNull(menuDTO)) {
            MenuEntity menu = new MenuEntity();
            BeanUtil.copyProperties(menuDTO, menu);
            return this.menuMapper.updateById(menu);
        } else {
            return 0;
        }
    }

    @Override
    public Integer deleteMenu(List<Long> ids) {
        if (ids.size() > 0) {
            return this.menuMapper.deleteBatchIds(ids);
        } else {
            return 0;
        }
    }
}
